package com.shawn.integeration.common.model.http;

import cn.hutool.core.map.MapUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.Map;

/**
 * Http 请求工具类
 *
 * @author: shawn
 * @Date: 2023/12/18 10:30
 * @Version 1.0.0
 */
public class HttpTool {
    private static Logger log = LoggerFactory.getLogger(HttpTool.class);

    public static <T> HttpRes<T> get(String url, Class<T> clazz) {
        return HttpTool.doGet(url, MapUtil.empty(), MapUtil.empty(), clazz);
    }

    public static <T> HttpRes<T> get(String url,Map<String, Object> paramMap, Class<T> clazz) {
        return HttpTool.doGet(url, paramMap, MapUtil.empty(), clazz);
    }

    public static <T> HttpRes<T> get(String url,Map<String, Object> paramMap,Map<String, String> headers, Class<T> clazz) {
        return HttpTool.doGet(url, paramMap, headers, clazz);
    }

    public static <T> HttpRes<T> postForm(String url, Map<String, Object> paramMap, Class<T> clazz) {
        return HttpTool.doPostForm(url, paramMap, MapUtil.empty(), clazz);
    }

    public static <T> HttpRes<T> postForm(String url, Map<String, Object> paramMap, Map<String, String> headers, Class<T> clazz) {
        return HttpTool.doPostForm(url, paramMap, headers, clazz);
    }

    public static <T> HttpRes<T> post(String url,String json, Class<T> clazz) {
        return HttpTool.doPost(url, json, MapUtil.empty(), clazz);
    }

    public static <T> HttpRes<T> post(String url,String json,Map<String, String> headers, Class<T> clazz) {
        return HttpTool.doPost(url, json, headers, clazz);
    }

    public static <T> HttpRes<T> doGet(String url, Map<String, Object> paramMap, Map<String, String> headers, Class<T> clazz) {
        // 1. 参数不为空,则将 URL与参数进行拼接
        if (MapUtil.isNotEmpty(paramMap)) {
            url = url + "?" + HttpUtil.toParams(paramMap, Charset.forName("UTF-8"));
        }
        // 2. 创建请求对象
        HttpRequest request = new HttpRequest(url);
        // 3. 设置头信息
        if (MapUtil.isNotEmpty(headers)) {
            request.addHeaders(headers);
        }
        // 4. 设置请求方式
        request.setMethod(Method.GET);
        // 5. 执行请求
        HttpResponse response;
        try {
            response = request.execute();
        } catch (Exception e) {
            log.error(String.format("接口[%s]请求失败", url), e);
            return HttpRes.error(e.getMessage());
        }

        // 6. 判断请求是否成功
        boolean success = response.isOk();
        if (!success) {
            return HttpRes.error("请求失败，状态码为 " + response.getStatus());
        }

        // 7. 解析请求参数
        String body = response.body();
        log.debug(String.format("接口[%s]请求返回信息[%s]", url, body));
        return HttpRes.success(JSONUtil.toBean(body, clazz));

    }

    public static <T> HttpRes<T> doPost(String url, String json, Map<String, String> headers, Class<T> clazz) {
        // 1. 创建请求对象
        HttpRequest request = new HttpRequest(url);

        // 2. 设置头信息
        if (MapUtil.isNotEmpty(headers)) {
            request.addHeaders(headers);
        }

        // 3. 设置请求方式
        request.setMethod(Method.POST);
        request.body(json);

        // 5. 执行请求
        HttpResponse response;
        try {
            response = request.execute();
        } catch (Exception e) {
            log.error(String.format("接口[%s]请求失败", url), e);
            return HttpRes.error(e.getMessage());
        }

        // 6. 判断请求是否成功
        boolean success = response.isOk();
        if (!success) {
            return HttpRes.error("请求失败，状态码为 " + response.getStatus());
        }

        // 7. 解析请求参数
        String body = response.body();
        log.debug(String.format("接口[%s]请求返回信息[%s]", url, body));
        return HttpRes.success(JSONUtil.toBean(body, clazz));
    }

    public static <T> HttpRes<T> doPostForm(String url, Map<String, Object> paramMap, Map<String, String> headers, Class<T> clazz) {
        // 1. 创建请求对象
        HttpRequest request = new HttpRequest(url);

        // 2. 设置头信息
        if (MapUtil.isNotEmpty(headers)) {
            request.addHeaders(headers);
        }

        // 3. 设置请求方式
        request.setMethod(Method.POST);
        request.form(paramMap);

        // 5. 执行请求
        HttpResponse response;
        try {
            response = request.execute();
        } catch (Exception e) {
            log.error(String.format("接口[%s]请求失败", url), e);
            return HttpRes.error(e.getMessage());
        }

        // 6. 判断请求是否成功
        boolean success = response.isOk();
        if (!success) {
            return HttpRes.error("请求失败，状态码为 " + response.getStatus());
        }

        // 7. 解析请求参数
        String body = response.body();
        log.debug(String.format("接口[%s]请求返回信息[%s]", url, body));
        return HttpRes.success(JSONUtil.toBean(body, clazz));
    }
}
